package br.ufc.si.sd.servidor;

import br.ufc.si.sd.email.SendMail;
import br.ufc.si.sd.skaletor.Gerenciador;
import com.google.protobuf.ByteString;
import com.google.protobuf.InvalidProtocolBufferException;
import java.net.*;
import java.io.*;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.mail.MessagingException;
import javax.mail.internet.AddressException;
import protos.br.ufc.si.sd.gerado.AgendaEletronica.AddressBook;
import protos.br.ufc.si.sd.gerado.AgendaEletronica.Person;
import protos.br.ufc.si.sd.gerado.Message.ResponseMessage;

public class Servidor {


    private int porta;
    private AddressBook.Builder addressBook;
    private Person dono;
    public static void main(String[] args) throws IOException {
        new Servidor(5000).executa();
    }

    public Servidor(int porta) {
        this.porta = porta;

        addressBook = AddressBook.newBuilder();
        

    }

    public void executa() throws IOException {
        ServerSocket servidor = new ServerSocket(this.porta);
        printf("Porta " + porta + " aberta!");

        while (true) {
            Socket cliente = servidor.accept();
            printf("Nova conexão com o cliente " + cliente.getInetAddress());
            PrintStream ps = new PrintStream(cliente.getOutputStream());
            Gerenciador ge = new Gerenciador(cliente, this);
            new Thread(ge).start();

        }
    }

    private void printf(String a) {
        System.out.println(a);
    }

    public byte[] addPerson(ByteString p) throws InvalidProtocolBufferException, IOException {

        Person per = Person.parseFrom(p.toByteArray());
        Integer id = new Integer(per.getId());
        ResponseMessage.Builder response = ResponseMessage.newBuilder();
        ResponseMessage resquest = ResponseMessage.parseFrom(this.getPerson(ByteString.copyFromUtf8(id.toString())));
        if (resquest.getResult().isEmpty()) {
            this.addressBook.addPerson(per);
            response.setMensagem("Adicionado com sucesso");
            return response.build().toByteArray();
        }
        response.setMensagem("Contato já cadastrado");
        return response.build().toByteArray();
    }
     public byte[] registrar(ByteString p) throws InvalidProtocolBufferException, IOException {

        Person per = Person.parseFrom(p.toByteArray());
        Integer id = new Integer(per.getId());
        ResponseMessage.Builder response = ResponseMessage.newBuilder();
        ResponseMessage resquest = ResponseMessage.parseFrom(this.getPerson(ByteString.copyFromUtf8(id.toString())));
        if (resquest.getResult().isEmpty()) {
            dono=per;
            response.setMensagem("Registrado com sucesso");
            return response.build().toByteArray();
        }
        response.setMensagem("Contato já cadastrado");
        return response.build().toByteArray();
    }

    public byte[] removePerson(ByteString p) throws InvalidProtocolBufferException, IOException {
        ResponseMessage.Builder response = ResponseMessage.newBuilder();
        Person per = Person.parseFrom(p.toByteArray());
        AddressBook.Builder book = AddressBook.newBuilder();
        boolean removeu = false;
        if (per != null) {
            for (int i = 0; i < this.addressBook.getPersonCount(); i++) {
                if (per.getId() == this.addressBook.getPersonList().get(i).getId()) {
                    removeu = true;
                    continue;
                }
                book.addPerson(addressBook.getPerson(i));
            }
            if (removeu) {
                this.addressBook = book;
                response.setMensagem("Removido com Sucesso");
                return response.build().toByteArray();
            }
            response.setMensagem("Erro ao Excluir Contato");
            return response.build().toByteArray();
        }
        response.setMensagem("Contato não encontrado");
        return response.build().toByteArray();

    }

    public byte[] updatePerson(ByteString con) throws InvalidProtocolBufferException, AddressException, MessagingException {
        ResponseMessage.Builder response = ResponseMessage.newBuilder();
        Person per = Person.parseFrom(con.toByteArray());
        AddressBook.Builder book = AddressBook.newBuilder();
        Person editada= null;
        boolean editou = false;
        if (per != null) {
            for (int i = 0; i < this.addressBook.getPersonCount(); i++) {
                if (per.getId() == this.addressBook.getPersonList().get(i).getId()) {
                    editada=this.addressBook.getPersonList().get(i);
                    book.addPerson(per);
                    editou = true;
                    continue;
                }
                book.addPerson(addressBook.getPerson(i));
            }
            if (editou) {
                this.addressBook = book;
                final String mensagem= "Sr(a). "+this.dono.getName()+", o seguinte contato acabou de ser alterado: \n" +
                        "ID : "+editada.getId()+";\n " +
                        "Nome : "+editada.getName()+";\n " +
                        "E-mail : "+editada.getEmail()+";\n " +
                        "Tel. Celular : "+editada.getCelular()+";\n " +
                        "Tel. Trabalho : "+editada.getTelTrabalho()+";\n " +
                        "Tel. Doméstico : "+editada.getTelDomestico()+";\n " +
                        "Para :\n" +
                        "ID : "+per.getId()+";\n " +
                        "Nome : "+per.getName()+";\n " +
                        "E-mail : "+per.getEmail()+";\n " +
                        "Tel. Celular : "+per.getCelular()+";\n " +
                        "Tel. Trabalho : "+per.getTelTrabalho()+";\n " +
                        "Tel. Doméstico : "+per.getTelDomestico()+";\n\n\n " +
                        "Obrigado por usar nosso serviço!";

                Thread t = new Thread(){
                   
                    @Override
                    public void run(){
                        try {
                            SendMail.sendMail(dono.getEmail(), "notificação de alteração de contatos", mensagem);
                            this.destroy();
                        } catch (AddressException ex) {
                            Logger.getLogger(Servidor.class.getName()).log(Level.SEVERE, null, ex);
                        } catch (MessagingException ex) {
                            Logger.getLogger(Servidor.class.getName()).log(Level.SEVERE, null, ex);
                        }
                    }

                };t.start();

               // SendMail.sendMail(this.dono.getEmail(),"notificação de alteração de contatos", men);
                response.setMensagem("Editado com Sucesso");
                return response.build().toByteArray();
            }
            response.setMensagem("Erro ao Editar Contato");
            return response.build().toByteArray();
        }
        response.setMensagem("Contato não encontrado");
        return response.build().toByteArray();
    }

    public byte[] listPeople(ByteString cons) {

        ResponseMessage.Builder response = ResponseMessage.newBuilder();
        if (this.addressBook.getPersonCount() > 0) {
            response.setMensagem("Os contatos são :");
            AddressBook.Builder book = AddressBook.newBuilder();
            book.addAllPerson(this.addressBook.getPersonList());
            response.setResult(book.build().toByteString());
            return response.build().toByteArray();
        }
        response.setMensagem("Sem contatos no momento");
        return response.build().toByteArray();
    }

    public byte[] getPerson(ByteString per) throws IOException {
        ResponseMessage.Builder response = ResponseMessage.newBuilder();
        Integer id = new Integer(per.toStringUtf8());
        for (int i = 0; i < addressBook.getPersonCount(); i++) {
            if (addressBook.getPersonList().get(i).getId() == id) {
                response.setMensagem("Contato encontrado :");
                response.setResult(this.addressBook.getPerson(i).toByteString());
                return response.build().toByteArray();
            }
        }
        response.setMensagem("Contato não encontrado:");
        byte[] a = new byte[0];
        response.setResult(ByteString.copyFrom(a));
        return response.build().toByteArray();
    }

    

}

